package com.uzhie.web.service;

import com.alibaba.fastjson.JSONObject;
import com.uzhie.exception.BussException;
import com.uzhie.exception.UserException;
import com.uzhie.exception.WarningException;
import com.uzhie.jt808.JT808Constant;
import com.uzhie.jt808.msg.entity.JT_8801;
import com.uzhie.jt808.service.JT808Service;
import com.uzhie.jt808.util.DateUtil;
import com.uzhie.util.ConstantKit;
import com.uzhie.web.bean.PageBean;
import com.uzhie.web.dao.*;
import com.uzhie.web.module.*;
import org.apache.ibatis.session.RowBounds;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by lilongfei on 2018/8/2.
 */
@Service
public class WarningService {

    @Autowired
    WarningDAO waringDAO;
    @Autowired
    WarningCollectDAO warningCollectDAO;
    @Autowired
    BaseDataDAO baseDataDAO;
    @Autowired
    CatalogDAO catalogDAO;
    @Autowired(required = false)
    JT808Service jt808Service;

    @Autowired(required = false)
    private JSDrivingAssistanceSystemWarnDAO jsDrivingAssistanceSystemWarnDAO;

    @Autowired(required = false)
    private JSDriverStatusMonitorSystemWarnDAO jsDriverStatusMonitorSystemWarnDAO;

    @Autowired(required = false)
    private JSTirePressureMonitorSystemWarnDAO jsTirePressureMonitorSystemWarnDAO;

    @Autowired(required = false)
    private JSBlindAreaMonitorSystemWarnDAO jsBlindAreaMonitorSystemWarnDAO;

    /**
     * 通过告警类型与所在部门,查询所有告警消息
     *
     * @param category 告警类型
     * @param userId   用户Id
     * @return
     */
    public List<Warning> queryListByTypeAndDepart(String category,
                                                  @NotNull(message = UserException.Status.ID_ISNULL) String userId,
                                                  String vehicleNumber, String driver, String startTime, String endTime,
                                                  @NotNull(message = BussException.PAGE_ISNULL) RowBounds page) throws UserException {

        List<Catalog> catalogs = catalogDAO.selectCatalogByUserId(userId);
        if (catalogs.size() == 0) throw new UserException(UserException.Status.NO_POWER_ERROR);
        List<String> departIds = new ArrayList<>();
        for (Catalog catalog : catalogs) {
            departIds.add(catalog.getId());
        }
        List<Warning> result = waringDAO.queryListByConditions(category, departIds, vehicleNumber, driver, startTime, endTime, page);
        return result;
    }


    /**
     * 获取所有报警类型和该类型累计未处理标签
     *
     * @return
     */
    public List<JSONObject> queryAllLebal(@NotEmpty(message = UserException.Status.USER_ISNULL) String userId) throws UserException {
        List<JSONObject> result = new ArrayList<>();
        //获取所有报警类型数据字典
        List<BaseData> baseDatas = baseDataDAO.queryListByCondition(String.valueOf(ConstantKit.BASEDATA.WARNING.getType()), ConstantKit.STATUS.IS_AVAILABLE, new RowBounds(1, 100000));
        //查询当前用户的部门管辖权限范围
        List<Catalog> catalogs = catalogDAO.selectCatalogByUserId(userId);
        if (catalogs.size() == 0) throw new UserException(UserException.Status.NO_POWER_ERROR);
        List<String> departIds = new ArrayList<>();
        for (Catalog catalog : catalogs) {
            departIds.add(catalog.getId());
        }
        //计算每个字典中的报警参数信息及未处理总条数
        for (BaseData baseData : baseDatas) {
            JSONObject obj = new JSONObject();
            obj.put("value", baseData.getdValue());
            obj.put("key", baseData.getdKey());
            obj.put("id", baseData.getId());
            Integer count = waringDAO.queryLabelByCategory(baseData.getdKey(), departIds);
            obj.put("label", count);
            result.add(obj);
        }
        return result;
    }

    /**
     * 更新告警信息状态
     *
     * @param warnings
     */
    public void updateWarningStatus(@NotEmpty(message = WarningException.Status.WARN_ERROR) @Valid List<Warning> warnings, Integer status,
                                    String remark, String handlerId, String handlerName) throws WarningException {
        //判断传递状态是否正确
        if (status != ConstantKit.WARNSTATUS.PENDING.getType()) {
            //处理告警时需要先判断告警是否为处于待处理状态
            for (Warning warning : warnings) {
                if (warning.getStatus() != ConstantKit.WARNSTATUS.PENDING.getType())
                    throw new WarningException(WarningException.Status.STATUS_ERROR);
            }
        } else
            //传递状态不正确,抛出异常
            throw new WarningException(WarningException.Status.HANLD_ERROR);
        for (Warning warning : warnings) {
            warning.setStatus(status);
            warning.setHandlerId(handlerId);
            warning.setHandlerName(handlerName);
            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String nowdayTime = dateFormat.format(new Date());
            try {
                Date nowDate = dateFormat.parse(nowdayTime);
                warning.setHandlerTime(nowDate);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            warning.setRemark(remark);
            waringDAO.updateByPrimaryKeySelective(warning);
        }
    }

    /**
     * 报警处理报表查询
     *
     * @param userId
     * @param simNumber
     * @param vehicleNumber
     * @param driver
     * @param telephone
     * @param handlerName
     * @param beginTime
     * @param endTime
     * @param handBeginTime
     * @param handEndTime
     * @return
     */
    public List<Warning> handlerReport(String userId, String simNumber, String vehicleNumber, String driver, String telephone, String handlerName, String beginTime, String endTime, String handBeginTime, String handEndTime, PageBean pageBean) {
        return waringDAO.handlerReport(userId, simNumber, vehicleNumber, driver, telephone, handlerName, beginTime, endTime, handBeginTime, handEndTime, pageBean.getRowBounds());
    }

    /*---------------------------------------报警通知处理------------------------------------------------------*/


    /**
     * 下发拍照指令
     *
     * @param vehicleNumber 车载设备sim卡
     * @param channel       通道号
     * @param takeOrder     拍照张数
     * @param resolution    分辨率
     */
    public void takePic(@NotEmpty(message = WarningException.Status.SIM_ERROR) String vehicleNumber,
                        @NotNull(message = WarningException.Status.CHANNEL_ISNULL) Integer channel,
                        @NotNull(message = WarningException.Status.TAKEORDER_ISNULL) Integer takeOrder,
                        @NotNull(message = WarningException.Status.RESOLUTION_ISNULL) Integer resolution) throws WarningException {
        try {
            JT_8801 order = new JT_8801(channel, takeOrder, resolution);
            jt808Service.post(JT808Constant.MSG_ID.PLA_REQ_CAMERA_TAKE, vehicleNumber, order.WriteToBytes());
        } catch (Exception e) {
            throw new WarningException(WarningException.NOT_ONLINE);
        }
    }



    /*---------------------------------------报警集合处理------------------------------------------------------*/


    /**
     * 通过用户管理权限，获取对应车辆告警信息的汇总展示
     *
     * @param userId        当前登录用户的Id
     * @param vehicleNumber
     * @param driver
     * @param beginTime
     * @param endTime
     * @param rowBounds
     * @return
     * @throws UserException
     */
    public List<WarningCollect> queryCollectByUserPowerAndCondition(String userId, String category, String vehicleNumber, String driver, String beginTime, String endTime, RowBounds rowBounds) throws UserException {
        List<Catalog> catalogs = catalogDAO.selectCatalogByUserId(userId);
        if (catalogs.size() == 0) throw new UserException(UserException.Status.NO_POWER_ERROR);
        List<String> departIds = new ArrayList<>();
        for (Catalog catalog : catalogs) {
            departIds.add(catalog.getId());
        }
        List<WarningCollect> collects = warningCollectDAO.queryByCondition(departIds, category, vehicleNumber, driver, beginTime, endTime, rowBounds);
        return collects;
    }

    /**
     * 批量处理报警信息
     *
     * @param warningCollects
     * @param status
     */
    public void updateWarningCollect(List<WarningCollect> warningCollects, String handlerId, String handlerName, String remark, Integer status) throws WarningException {
        if (warningCollects.size() == 0) throw new WarningException(WarningException.Status.WARN_ERROR);
        if (status == null || status == 0) throw new WarningException(WarningException.Status.HANLD_ERROR);
        //批量处理报警数据
        for (WarningCollect collect : warningCollects) {
            collect.setStatus(status);
            collect.setHandlerId(handlerId);
            collect.setHandlerName(handlerName);
            collect.setRemark(remark);
            collect.setHandlerTime(new Date());
            warningCollectDAO.updateByPrimaryKey(collect);
            waringDAO.updateBySimAndTimeFrame(collect.getSimNumber(), collect.getCategory(), DateUtil.dateToString(collect.getStartTime()), DateUtil.dateToString(collect.getEndTime()), status,
                    collect.getHandlerId(), collect.getHandlerName(), collect.getHandlerTime(), collect.getRemark());
        }
    }

    /*---------------------------------------苏标报警处理------------------------------------------------------*/

    /**
     * 苏标 高级驾驶辅助系统报警
     *
     * @param vehicleNo 车牌号
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @param pageBean
     * @return
     */
    public List<Map<String, Object>> queryJSDrivingAssistanceSystemWarn(String vehicleNo, String startTime, String endTime, PageBean pageBean) {
        return jsDrivingAssistanceSystemWarnDAO.selectList(vehicleNo, startTime, endTime, pageBean.getRowBounds());
    }

    /**
     * 苏标 驾驶员状态监测报警
     *
     * @param vehicleNo 车牌号
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @param pageBean
     * @return
     */
    public List<Map<String, Object>> queryJSDriverStatusMonitorSystemWarn(String vehicleNo, String startTime, String endTime, PageBean pageBean) {
        return jsDriverStatusMonitorSystemWarnDAO.selectList(vehicleNo, startTime, endTime, pageBean.getRowBounds());
    }

    /**
     * 苏标 胎压监测报警
     *
     * @param vehicleNo 车牌号
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @param pageBean
     * @return
     */
    public List<Map<String, Object>> queryJSTirePressureMonitorSystemWarn(String vehicleNo, String startTime, String endTime, PageBean pageBean) {
        return jsTirePressureMonitorSystemWarnDAO.selectList(vehicleNo, startTime, endTime, pageBean.getRowBounds());
    }

    /**
     * 苏标 盲区监测报警
     *
     * @param vehicleNo 车牌号
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @param pageBean
     * @return
     */
    public List<Map<String, Object>> queryJSBlindAreaMonitorSystemWarn(String vehicleNo, String startTime, String endTime, PageBean pageBean) {
        return jsBlindAreaMonitorSystemWarnDAO.selectList(vehicleNo, startTime, endTime, pageBean.getRowBounds());
    }

    public boolean updateJSDrivingAssistanceSystemWarn(@NotBlank(message = "ID不可为空") String id, @NotBlank(message = "备注不可为空") String remark, Integer status) {
        JSDrivingAssistanceSystemWarn warn = new JSDrivingAssistanceSystemWarn();
        warn.setId(id);
        warn.setRemark(remark);
        warn.setStatus(status);
        warn.setUpdateTime(new Date());
        int i = jsDrivingAssistanceSystemWarnDAO.updateByPrimaryKeySelective(warn);
        return 1 == i;
    }

    public boolean updateJSDriverStatusMonitorSystemWarn(@NotBlank(message = "ID不可为空") String id, @NotBlank(message = "备注不可为空") String remark, Integer status) {
        JSDriverStatusMonitorSystemWarn warn = new JSDriverStatusMonitorSystemWarn();
        warn.setId(id);
        warn.setRemark(remark);
        warn.setStatus(status);
        warn.setUpdateTime(new Date());
        int i = jsDriverStatusMonitorSystemWarnDAO.updateByPrimaryKeySelective(warn);
        return 1 == i;
    }

    public boolean updateJSTirePressureMonitorSystemWarn(@NotBlank(message = "ID不可为空") String id, @NotBlank(message = "备注不可为空") String remark, Integer status) {
        JSTirePressureMonitorSystemWarn warn = new JSTirePressureMonitorSystemWarn();
        warn.setId(id);
        warn.setRemark(remark);
        warn.setStatus(status);
        warn.setUpdateTime(new Date());
        int i = jsTirePressureMonitorSystemWarnDAO.updateByPrimaryKeySelective(warn);
        return 1 == i;
    }

    public boolean updateJSBlindAreaMonitorSystemWarn(@NotBlank(message = "ID不可为空") String id, @NotBlank(message = "备注不可为空") String remark, Integer status) {
        JSBlindAreaMonitorSystemWarn warn = new JSBlindAreaMonitorSystemWarn();
        warn.setId(id);
        warn.setRemark(remark);
        warn.setStatus(status);
        warn.setUpdateTime(new Date());
        int i = jsBlindAreaMonitorSystemWarnDAO.updateByPrimaryKeySelective(warn);
        return 1 == i;
    }

}
